/*
 * Copyright 2008 Mark Davidson.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */

package org.doofer.test

import com.documentum.fc.client.*
import org.doofer.*

/**
 * Tests for SessionUtil
 */
class SessionUtilTest extends DooferBaseTest {
    
    void forceConnectionFailure(Map params) {
        final def su = new SessionUtil(params)
        def session = null
        
        try {
            session = su.connect()
        } finally {
            su.disconnect(session: session)
        }
    }

    void testSession() {
        def failed = false
        def session = null
        final def params = [username: username, password: password, repository: repository]
        final def options = [asUser: impersonated]
        final def su = new SessionUtil(params)

        // test session failures
        shouldFail(DfAuthenticationException) { forceConnectionFailure([username: 'invalid', password: password, repository: repository]) }
        shouldFail(DfAuthenticationException) { forceConnectionFailure([username: username, password: 'invalid', repository: repository]) }
        if(DfClient.getDFCVersion().startsWith('6.'))
            shouldFail(DfNoServersException) { forceConnectionFailure([username: username, password: password, repository: 'invalid']) }
        else
            shouldFail(DfDocbaseUnreachableException) { forceConnectionFailure([username: username, password: password, repository: 'invalid']) }

        // test manual connection/disconnection
        failed = false
        try {
            session = su.connect()
            assert(session)
            assertEquals(repository, session.docbaseName)
            assertEquals(username, session.loginUserName)
            println "Connected to ${session.docbaseName} as ${session.loginUserName}"
        } catch (Throwable t) {
            println "Failed to connect to repository ${t.message}"
            failed = true
        } finally {
            su.disconnect(session: session)
            println "Disconnected ok"
        }
        assertFalse(failed)

        // test connection/disconnection with resource cleanup
        try {
            su.useSession { sesh ->
                assert(sesh)
                assertEquals(repository, sesh.docbaseName)
                assertEquals(username, sesh.loginUserName)
                println "Connected to ${sesh.docbaseName} as ${sesh.loginUserName}"
            }
            println "Disconnected ok"
        } catch (Throwable t) {
            println "Detected error: ${t.message}"
            failed = true
        }
        assertFalse(failed)

        // test connection/disconnection with resource cleanup & session context
        try {
            su.withSession {
                assertEquals(repository, docbaseName)
                assertEquals(username, loginUserName)
            }
            println "Disconnected ok"
        } catch(Throwable t) {
            println "Detected error: $t.message"
            failed = true
        }
        assertFalse(failed)

        // test session impersonation
        try {
            su.useSession(options) { sesh ->
                assert(sesh)
                assertEquals(repository, sesh.docbaseName)
                assertEquals(impersonated, sesh.loginUserName)
                println "Connected to ${sesh.docbaseName} as ${sesh.loginUserName}"
            }
            println "Disconnected ok"
        } catch (Throwable t) {
            println "Detected error: ${t.message}"
            failed = true
        }
        assertFalse(failed)
    }
}